using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Infrastructure.Aspect.Services.Traslator
{
    public abstract class EntityMapperTranslator<TBusinessEntity, TServiceEntity> : BaseTranslator
    {
        public override bool CanTranslate(Type targetType, Type sourceType)
        {
            return (targetType == typeof(TBusinessEntity) && sourceType == typeof(TServiceEntity)) ||
                (targetType == typeof(TServiceEntity) && sourceType == typeof(TBusinessEntity));
        }

        public override object Translate(IEntityTranslatorService service, Type targetType, object source)
        {
            if (targetType == typeof(TBusinessEntity))
                return ServiceToBusiness(service, (TServiceEntity)source);
            if (targetType == typeof(TServiceEntity))
                return BusinessToService(service, (TBusinessEntity)source);

            throw new EntityTranslatorException();
        }

        protected abstract TServiceEntity BusinessToService(IEntityTranslatorService service, TBusinessEntity value);
        protected abstract TBusinessEntity ServiceToBusiness(IEntityTranslatorService service, TServiceEntity value);
    }
    public abstract class EntityEnumerableMapperTranslator<TBusinessEntity, TServiceEntity> : BaseTranslator
    {
        public override bool CanTranslate(Type targetType, Type sourceType)
        {
            if (targetType.GetInterface("System.Collections.IEnumerable", false) != null
                && sourceType.GetInterface("System.Collections.IEnumerable", false) != null
                && targetType.IsGenericType == true && sourceType.IsGenericType == true)
            {
                var target = targetType.GetGenericArguments().ElementAt(0);
                var source = sourceType.GetGenericArguments().ElementAt(0);

                var res = (target == typeof(TBusinessEntity) && source == typeof(TServiceEntity)) || (target == typeof(TServiceEntity) && source == typeof(TBusinessEntity));
                return res;

            }
            return false;
        }

        public override object Translate(IEntityTranslatorService service, Type targetType, object source)
        {
            if (targetType == typeof(IEnumerable<TBusinessEntity>))
                return ServiceToBusiness(service, (IEnumerable<TServiceEntity>)source);
            if (targetType == typeof(IEnumerable<TServiceEntity>))
                return BusinessToService(service, (IEnumerable<TBusinessEntity>)source);
            throw new EntityTranslatorException();
        }

        protected abstract IEnumerable<TServiceEntity> BusinessToService(IEntityTranslatorService service, IEnumerable<TBusinessEntity> value);
        protected abstract IEnumerable<TBusinessEntity> ServiceToBusiness(IEntityTranslatorService service, IEnumerable<TServiceEntity> value);
    }
}
